﻿using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

[CreateAssetMenu(fileName = "Room_", menuName = "游戏SO文件/地牢/房间")]
public class RoomTemplateSO : ScriptableObject
{
    [HideInInspector] public string guid;

    #region Header ROOM PREFAB

    [Space(10)]
    [Header("房间预制体")]

    #endregion Header ROOM PREFAB

    #region Tooltip

    [Tooltip("房间的游戏对象预制件（这将包含房间和环境游戏对象的所有瓦片贴图")]

    #endregion Tooltip

    public GameObject prefab;

    [HideInInspector] public GameObject previousPrefab; // 如果复制了 SO 并更改了预制件，则用于重新生成 GUID
    
    #region Header ROOM MUSIC

    [Space(10)]
    [Header("房间音乐")]

    #endregion Header ROOM MUSIC

    #region Tooltip

    [Tooltip("战斗音乐 SO 当房间里没有敌人时")]

    #endregion Tooltip

    public MusicTrackSO battleMusic;

    #region Tooltip

    [Tooltip("环境音乐 SO 当房间里的敌人被清除时")]

    #endregion Tooltip

    public MusicTrackSO ambientMusic;


    #region Header ROOM CONFIGURATION

    [Space(10)]
    [Header("房间配置")]

    #endregion Header ROOM CONFIGURATION

    #region Tooltip

    [Tooltip(
        "房间节点类型 SO。房间节点类型对应于房间节点图中使用的房间节点。 走廊是例外。 在房间节点图中，只有一种走廊类型“走廊”。 对于房间模板，有 2 种走廊节点类型 - CorridorNS 和 CorridorEW。")]

    #endregion Tooltip

    public RoomNodeTypeSO roomNodeType;

    #region Tooltip

    [Tooltip(
        "如果您想象一个围绕房间瓦片地图的矩形完全包围了它，则房间的下边界表示该矩形的左下角。这应该根据房间的瓦片图来确定（使用坐标画笔指针获取左下角的瓦片图网格位置（注意：这是本地瓦片图位置，而不是世界位置")]

    #endregion Tooltip

    public Vector2Int lowerBounds;

    #region Tooltip

    [Tooltip(
        "如果您想象一个围绕房间瓦片地图的矩形完全包围它，则房间的上限边界表示该矩形的右上角。这应该根据房间的瓦片图来确定（使用坐标画笔指针获取该右上角的瓦片图网格位置（注意：这是本地瓦片图位置，而不是世界位置")]

    #endregion Tooltip

    public Vector2Int upperBounds;

    #region Tooltip

    [Tooltip(
        "一个房间最多应该有四个门口 - 每个指南针方向一个。 这些应该具有一致的 3 个瓷砖开口尺寸，中间瓷砖位置是门口坐标“位置”")]

    #endregion Tooltip

    [SerializeField]
    public List<Doorway> doorwayList;

    #region Tooltip

    [Tooltip(
        "在瓦片地图坐标中，房间的每个可能的生成位置（用于敌人和箱子）都应该添加到此数组中")]

    #endregion Tooltip

    public Vector2Int[] spawnPositionArray;

    #region Header ENEMY DETAILS

    [Space(10)]
    [Header("敌人详细信息")]

    #endregion Header ENEMY DETAILS

    #region Tooltip

    [Tooltip("在列表中填充所有可以按地牢级别在此房间中生成的敌人，包括将生成的此敌人类型的比例（随机）")]

    #endregion Tooltip

    public List<SpawnableObjectsByLevel<EnemyDetailsSO>> enemiesByLevelList;

    #region Tooltip

    [Tooltip("使用敌人的生成参数填充列表.")]

    #endregion Tooltip

    public List<RoomEnemySpawnParameters> roomEnemySpawnParametersList;

    /// <summary>
    /// 返回房间模板的入口列表
    /// </summary>
    public List<Doorway> GetDoorwayList()
    {
        return doorwayList;
    }

    #region Validation

#if UNITY_EDITOR

    // 验证 SO 字段
    private void OnValidate()
    {
        // 如果为空或预制件发生更改，请设置唯一的 GUID
        if (guid == "" || previousPrefab != prefab)
        {
            guid = GUID.Generate().ToString();
            previousPrefab = prefab;
            EditorUtility.SetDirty(this);
        }

        HelperUtilities.ValidateCheckNullValue(this, nameof(prefab), prefab);
        HelperUtilities.ValidateCheckNullValue(this, nameof(battleMusic), battleMusic);
        HelperUtilities.ValidateCheckNullValue(this, nameof(ambientMusic), ambientMusic);
        HelperUtilities.ValidateCheckNullValue(this, nameof(roomNodeType), roomNodeType);
        HelperUtilities.ValidateCheckEnumerableValues(this, nameof(doorwayList), doorwayList);

        // 检查关卡的敌人和房间生成参数
        if (enemiesByLevelList.Count > 0 || roomEnemySpawnParametersList.Count > 0)
        {
            HelperUtilities.ValidateCheckEnumerableValues(this, nameof(enemiesByLevelList), enemiesByLevelList);
            HelperUtilities.ValidateCheckEnumerableValues(this, nameof(roomEnemySpawnParametersList),
                roomEnemySpawnParametersList);

            foreach (RoomEnemySpawnParameters roomEnemySpawnParameters in roomEnemySpawnParametersList)
            {
                HelperUtilities.ValidateCheckNullValue(this, nameof(roomEnemySpawnParameters.dungeonLevel),
                    roomEnemySpawnParameters.dungeonLevel);
                HelperUtilities.ValidateCheckPositiveRange(this,
                    nameof(roomEnemySpawnParameters.minTotalEnemiesToSpawn),
                    roomEnemySpawnParameters.minTotalEnemiesToSpawn,
                    nameof(roomEnemySpawnParameters.maxTotalEnemiesToSpawn),
                    roomEnemySpawnParameters.maxTotalEnemiesToSpawn, true);
                HelperUtilities.ValidateCheckPositiveRange(this, nameof(roomEnemySpawnParameters.minSpawnInterval),
                    roomEnemySpawnParameters.minSpawnInterval, nameof(roomEnemySpawnParameters.maxSpawnInterval),
                    roomEnemySpawnParameters.maxSpawnInterval, true);
                HelperUtilities.ValidateCheckPositiveRange(this, nameof(roomEnemySpawnParameters.minConcurrentEnemies),
                    roomEnemySpawnParameters.minConcurrentEnemies,
                    nameof(roomEnemySpawnParameters.maxConcurrentEnemies),
                    roomEnemySpawnParameters.maxConcurrentEnemies, false);

                bool isEnemyTypesListForDungeonLevel = false;

                // 验证敌人类型列表
                foreach (SpawnableObjectsByLevel<EnemyDetailsSO> dungeonObjectsByLevel in enemiesByLevelList)
                {
                    if (dungeonObjectsByLevel.dungeonLevel == roomEnemySpawnParameters.dungeonLevel &&
                        dungeonObjectsByLevel.spawnableObjectRatioList.Count > 0)
                        isEnemyTypesListForDungeonLevel = true;

                    HelperUtilities.ValidateCheckNullValue(this, nameof(dungeonObjectsByLevel.dungeonLevel),
                        dungeonObjectsByLevel.dungeonLevel);

                    foreach (SpawnableObjectRatio<EnemyDetailsSO> dungeonObjectRatio in dungeonObjectsByLevel
                                 .spawnableObjectRatioList)
                    {
                        HelperUtilities.ValidateCheckNullValue(this, nameof(dungeonObjectRatio.dungeonObject),
                            dungeonObjectRatio.dungeonObject);

                        HelperUtilities.ValidateCheckPositiveValue(this, nameof(dungeonObjectRatio.ratio),
                            dungeonObjectRatio.ratio, false);
                    }
                }

                if (isEnemyTypesListForDungeonLevel == false && roomEnemySpawnParameters.dungeonLevel != null)
                {
                    Debug.Log("在地牢级别中没有指定敌人类型 " +
                              roomEnemySpawnParameters.dungeonLevel.levelName + " 在 GameObject 中 " +
                              this.name.ToString());
                }
            }
        }

        // 检查填充的生成位置
        HelperUtilities.ValidateCheckEnumerableValues(this, nameof(spawnPositionArray), spawnPositionArray);
    }

#endif

    #endregion Validation
}